package com.njcb.ams.support.security.service;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.njcb.ams.util.AmsUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import com.njcb.ams.pojo.dto.standard.EntityResponse;
import com.njcb.ams.portal.SysBaseDefine;
import com.njcb.ams.factory.comm.DataBus;
import com.njcb.ams.factory.comm.WebGlobalInfo;
import com.njcb.ams.support.config.AmsConfigUtil;
import com.njcb.ams.support.security.bo.SecurityUser;
import com.njcb.ams.support.security.bo.SessionModel;
import com.njcb.ams.support.security.config.AmsSecurityConfiguration;
import com.njcb.ams.support.security.util.TokenUtil;
import com.njcb.ams.util.AmsDateUtils;
import com.njcb.ams.util.AmsJsonUtils;

import io.jsonwebtoken.Claims;

/**
 * @author liuyanlong
 */
@Component
public class LoginSuccessAuthenticationHandler implements AuthenticationSuccessHandler {
    /**
     * 重定向参数
     */
    public static final String REDIRECT = "redirect";

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
                                        Authentication authentication) throws IOException, ServletException {
        response.setContentType("application/json;charset=utf-8");

        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT, GET");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, If-Modified-Since");
        //允许携带cookie
        response.setHeader("Access-Control-Allow-Credentials", "true");


        SecurityUser securityUser = securityUserHandle(request);
        /**
         * 如果有重定向参数,则重定向URL
         */
        String redirectUrl = request.getParameter(REDIRECT);
        if (AmsUtils.isNotNull(redirectUrl)) {
            response.sendRedirect(request.getContextPath() + redirectUrl);
        }
        PrintWriter out = response.getWriter();
        out.write(AmsJsonUtils.objectToJson(EntityResponse.build(securityUser)));
        out.flush();
        out.close();
    }

    /**
     * 处理SecurityUser
     * @param request
     * @return
     */
    public SecurityUser securityUserHandle(HttpServletRequest request){
        SecurityContext ctx = SecurityContextHolder.getContext();
        Authentication auth = ctx.getAuthentication();
        SecurityUser securityUser = new SecurityUser();
        if (auth.getPrincipal() instanceof UserDetails) {
            securityUser = (SecurityUser) auth.getPrincipal();
            securityUser.setSysName(StringUtils.isEmpty(SysBaseDefine.SYS_NAME) ? "管理系统" : SysBaseDefine.SYS_NAME);
            securityUser.setLoginIp(request.getRemoteAddr());
            securityUser.setLoginTime(AmsDateUtils.getCurrentTime14());
            WebGlobalInfo globalInfo = TokenAuthFilter.initWebGlobalInfo(securityUser);
            DataBus.setCurrentInstance(globalInfo);
            WebGlobalInfo.setGlobalInfo2HttpSession(request.getSession(), globalInfo);
            DataBus.setObject(securityUser);
            securityUser.setToken("no activate");
            AmsSecurityConfiguration securityConfig = AmsConfigUtil.getBean(AmsSecurityConfiguration.class);
            if (SessionModel.TOKEN.equals(securityConfig.sessionModel())) {
                String token = TokenUtil.createToken(securityUser);
                Claims claims = TokenUtil.parseToken(token);
                Map<String, Object> map = new HashMap<String, Object>();
                map.putAll(claims);
                securityConfig.storage(claims.getId(), map);
                securityUser.setToken(token);
            }
            securityConfig.updateUser(securityUser);
        } else {
            System.out.println(auth.getPrincipal());
        }
        return securityUser;
    }

}
